#include "include/util.h"

struct ring_queue *queue_alloc(u64 node_size, u64 node_num) {
    struct ring_queue *ring_queue;
    ring_queue = vmalloc(sizeof(struct ring_queue));
    ring_queue->queue = vmalloc(node_num * node_size);
    ring_queue->node_num = node_num;
    ring_queue->node_size = node_size;
    ring_queue->head = 0;
    ring_queue->tail = 0;
    return ring_queue;
}

void queue_push(struct ring_queue *ring_queue, void *node, u64 node_size) {
    void *addr;
    if ((ring_queue->tail == ring_queue->head + 1) ||
        (ring_queue->tail == 0 &&
         ring_queue->head + 1 == ring_queue->node_num)) {
        WARNING("%s: ring_queue is full", __func__);
        return;
    }
    addr = ring_queue->queue + ring_queue->head * ring_queue->node_size;

    memcpy(addr, node, node_size);
    ring_queue->head += 1;
    if (ring_queue->head >= ring_queue->node_num) {
        ring_queue->head = 0;
    }
}

void *queue_pop(struct ring_queue *ring_queue) {
    void *addr;
    if (ring_queue->head == ring_queue->tail) {
        return 0;
    }

    addr = ring_queue->queue + ring_queue->tail * ring_queue->node_size;

    ring_queue->tail += 1;
    if (ring_queue->tail >= ring_queue->node_num) {
        ring_queue->tail = 0;
    }
    return addr;
}

void queue_free(struct ring_queue *ring_queue) {
    vfree(ring_queue->queue);
    vfree(ring_queue);
}

u64 cal_page_size(u64 size, u64 index) {
    if (size - index * VM_PAGE_SIZE < 0) {
        return 0;
    } else {
        if (size - index * VM_PAGE_SIZE < VM_PAGE_SIZE) {
            return (size - index * VM_PAGE_SIZE);
        } else {
            return VM_PAGE_SIZE;
        }
    }
}